/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package gapktool;

import java.awt.AWTException;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.event.KeyEvent;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.io.IOException;

/**
 *
 * @author Administrator
 */
public class Xapk implements Runnable {

    private String apkfile;
    private String codedir;
    private String apkName;
    private String classfilePath;
    private String thisjardir;
    private String smali;
    private String jdgui;
    private javax.swing.JLabel jLabel;

    Xapk(String thisjardir1, String jTextField1text, String jTextField2text, String smali1, javax.swing.JLabel jLabel3, String jdgui6) {
        this.apkfile = jTextField1text;
        this.codedir = jTextField2text;
        this.thisjardir = thisjardir1;
        this.smali = smali1;
        this.jLabel = jLabel3;
        this.jdgui = jdgui6;
    }
       public static String replace(String strSource, String strFrom, String strTo)  
      {  
           // 如果要替换的子串为空，则直接返回源串  
           if(strFrom == null || strFrom.equals(""))  
               return strSource;  
           String strDest = "";  
           // 要替换的子串长度  
           int intFromLen = strFrom.length();  
           int intPos;  
           // 循环替换字符串  
           while((intPos = strSource.indexOf(strFrom)) != -1)  
           {  
               // 获取匹配字符串的左边子串  
               strDest = strDest + strSource.substring(0,intPos);  
               // 加上替换后的子串  
               strDest = strDest + strTo;  
               // 修改源串为匹配子串后的子串  
               strSource = strSource.substring(intPos + intFromLen);  
           }  
           // 加上没有匹配的子串  
           strDest = strDest + strSource;  
           // 返回  
           return strDest;  
       }  
    protected static void setClipboardText(Clipboard clip, String writeMe) {
        Transferable tText = new StringSelection(writeMe);
        clip.setContents(tText, null);
    }

    protected static String getClipboardText(Clipboard clip) throws Exception {
// 获取剪切板中的内容 
        Transferable clipT = clip.getContents(null);
        if (clipT != null) {
// 检查内容是否是文本类型 
            if (clipT.isDataFlavorSupported(DataFlavor.stringFlavor)) {
                return (String) clipT.getTransferData(DataFlavor.stringFlavor);
            }
        }
        return null;
    }

    @Override
    public void run() {
        ClassToJava ctj = new ClassToJava();
        Process process = null;

        Clipboard sysc = Toolkit.getDefaultToolkit().getSystemClipboard();

        //begin-----apktool解压资源文件
        try {
            String fName = this.apkfile;
            File tempFile = new File(fName.trim());
            this.apkName = tempFile.getName().substring(0, tempFile.getName().lastIndexOf("."));
            ctj.deleteFile(new File(codedir + "\\" + apkName));//删除存在的目录
            process = Runtime.getRuntime().exec("cmd /c " + thisjardir + "\\lib\\apktool1.4\\apktool.bat d " + this.apkfile + " " + this.codedir + "\\" + apkName);
            BufferedInputStream in = new BufferedInputStream(process.getInputStream());
            BufferedReader br = new BufferedReader(new InputStreamReader(in));
            String str;
            while ((str = br.readLine()) != null) {
                System.out.println(str);
                if (str.indexOf("Input") != -1) {
                    //apk文件不存在
                }
                if (str.indexOf("overwrite") != -1) {
                    //输出目录不为空
                }
            }
            process.waitFor();
            process.destroy();
        } catch (Exception ex) {
        }
        //end----apktool解压资源文件

        //begin 解压dex
        try {
            String fileName = this.apkfile;
            String filePath = this.codedir + "\\" + apkName + "\\dex\\";
            ZipFile zipFile = new ZipFile(fileName);
            Enumeration emu = zipFile.entries();
            while (emu.hasMoreElements()) {
                ZipEntry entry = (ZipEntry) emu.nextElement();
                if (entry.isDirectory()) {
                    new File(filePath + entry.getName()).mkdirs();
                    continue;
                }
                if (entry.getName().equals("classes.dex")) {
                    BufferedInputStream bis = new BufferedInputStream(zipFile.getInputStream(entry));
                    File file = new File(filePath + entry.getName());
                    File parent = file.getParentFile();
                    if ((parent != null) && (!parent.exists())) {
                        parent.mkdirs();
                    }
                    FileOutputStream fos = new FileOutputStream(file);
                    BufferedOutputStream bos = new BufferedOutputStream(fos, 2048);

                    byte[] data = new byte[2048];
                    int count;
                    while ((count = bis.read(data, 0, 2048)) != -1) {
                        bos.write(data, 0, count);
                    }
                    bos.flush();
                    bos.close();
                    bis.close();
                }
            }
            zipFile.close();
        } catch (Exception e) {
        }
        //end--------- 解压dex
        setClipboardText(sysc, this.codedir + "\\" + apkName + "\\dex\\");
        //begin-------dextojar
        try {
            process = Runtime.getRuntime().exec("cmd /c " + thisjardir + "\\lib\\dex2jar\\dex2jar.bat " + this.codedir + "\\" + this.apkName + "\\dex\\classes.dex");
            BufferedInputStream dexin = new BufferedInputStream(process.getInputStream());
            BufferedReader dexbr = new BufferedReader(new InputStreamReader(dexin));
            String dex2jarstr;
            while ((dex2jarstr = dexbr.readLine()) != null) {
                System.out.println(dex2jarstr);
            }
            process.waitFor();
            process.destroy();
        } catch (Exception ex) {
        }
        //end-------dextojar



        //begin-----反编译class

        if (this.jdgui.equals("yes")) {
            try {
                process = Runtime.getRuntime().exec("cmd /c " + thisjardir + "\\lib\\jd-gui-0.3.3\\jd-gui.exe " + this.codedir + "\\" + this.apkName + "\\dex\\classes_dex2jar.jar");
                Thread.sleep(1000);
                Robot robot;
                try {
                    robot = new Robot();
                    robot.keyPress(KeyEvent.VK_ALT);
                    robot.keyPress(KeyEvent.VK_F);
                    robot.keyRelease(KeyEvent.VK_F);
                    Thread.sleep(600);
                    robot.keyPress(KeyEvent.VK_S);
                    robot.keyRelease(KeyEvent.VK_S);
                    Thread.sleep(600);
                    robot.keyPress(KeyEvent.VK_D);
                    robot.keyRelease(KeyEvent.VK_D);
                    robot.keyRelease(KeyEvent.VK_ALT);
                    Thread.sleep(600);
                    robot.keyPress(KeyEvent.VK_CONTROL);
                    robot.keyPress(KeyEvent.VK_V);
                    robot.keyRelease(KeyEvent.VK_V);
                    robot.keyRelease(KeyEvent.VK_CONTROL);
                    Thread.sleep(600);
                    robot.keyPress(KeyEvent.VK_ENTER);
                    robot.keyRelease(KeyEvent.VK_ENTER);
                    Thread.sleep(600);
                    robot.keyPress(KeyEvent.VK_ALT);
                    robot.keyPress(KeyEvent.VK_S);
                    robot.keyRelease(KeyEvent.VK_S);
                    robot.keyRelease(KeyEvent.VK_ALT);                    
                    Thread.sleep(600);
                    robot.keyPress(KeyEvent.VK_Y);
                    robot.keyRelease(KeyEvent.VK_Y);
                    Thread.sleep(600);
                    robot.keyPress(KeyEvent.VK_ALT);
                    robot.keyPress(KeyEvent.VK_X);
                    robot.keyRelease(KeyEvent.VK_ALT);
                    robot.keyRelease(KeyEvent.VK_X);
                } catch (AWTException ex) {
                }
                process.waitFor();
                process.destroy();
                //begin-----解压JAVAZIP
                String rpath="";
                try {
                    String fileName = this.codedir + "\\" + this.apkName + "\\dex\\classes_dex2jar.src.zip";
                    this.classfilePath = this.codedir + "\\" + this.apkName + "\\src\\";
                    ZipFile zipFile = new ZipFile(fileName);
                    Enumeration emu = zipFile.entries();
                    while (emu.hasMoreElements()) {
                        ZipEntry entry = (ZipEntry) emu.nextElement();
                        if (entry.isDirectory()) {
                            new File(this.classfilePath + entry.getName()).mkdirs();
                            continue;
                        }
               
                        if (entry.getName().split("R.").length > 1) { 
                            if (entry.getName().split("R.")[1].equals("java")) {
                                 rpath= replace(entry.getName().split("R.")[0],"/","\\");
                            }
                        }
                        BufferedInputStream bis = new BufferedInputStream(zipFile.getInputStream(entry));
                        File file = new File(this.classfilePath + entry.getName());
                        File parent = file.getParentFile();
                        if ((parent != null) && (!parent.exists())) {
                            parent.mkdirs();
                        }
                        FileOutputStream fos = new FileOutputStream(file);
                        BufferedOutputStream bos = new BufferedOutputStream(fos, 2048);

                        byte[] data = new byte[2048];
                        int count;
                        while ((count = bis.read(data, 0, 2048)) != -1) {
                            bos.write(data, 0, count);
                        }
                        bos.flush();
                        bos.close();
                        bis.close();
                    }
                    zipFile.close();
                } catch (IOException e) {
                }
                //end-----解压JAVAZIP
                File dataDir = new File(this.codedir + "\\" + this.apkName + "\\gen\\"+rpath);
                if (!dataDir.exists()) {
                    dataDir.mkdirs();
                }
                //begin------转移R.java
                try {
                    process = Runtime.getRuntime().exec("cmd /c move " + this.codedir + "\\" + this.apkName + "\\src\\"+rpath+"R.java  " + this.codedir + "\\" + this.apkName + "\\gen\\"+rpath);
                    BufferedInputStream dexin = new BufferedInputStream(process.getInputStream());
                    BufferedReader dexbr = new BufferedReader(new InputStreamReader(dexin));
                    String dex2jarstr;
                    while ((dex2jarstr = dexbr.readLine()) != null) {
                        
                    }
                    process.waitFor();
                    process.destroy();
                } catch (Exception ex) {
                }
                //end-------转移R.java


            } catch (Exception ex) {
            }
        } else {

            //begin-----解压jar
            try {
                String fileName = this.codedir + "\\" + this.apkName + "\\dex\\classes_dex2jar.jar";
                this.classfilePath = this.codedir + "\\" + this.apkName + "\\class\\";
                ZipFile zipFile = new ZipFile(fileName);
                Enumeration emu = zipFile.entries();
                while (emu.hasMoreElements()) {
                    ZipEntry entry = (ZipEntry) emu.nextElement();
                    if (entry.isDirectory()) {
                        new File(this.classfilePath + entry.getName()).mkdirs();
                        continue;
                    }
                    BufferedInputStream bis = new BufferedInputStream(zipFile.getInputStream(entry));
                    File file = new File(this.classfilePath + entry.getName());
                    File parent = file.getParentFile();
                    if ((parent != null) && (!parent.exists())) {
                        parent.mkdirs();
                    }
                    FileOutputStream fos = new FileOutputStream(file);
                    BufferedOutputStream bos = new BufferedOutputStream(fos, 2048);

                    byte[] data = new byte[2048];
                    int count;
                    while ((count = bis.read(data, 0, 2048)) != -1) {
                        bos.write(data, 0, count);
                    }
                    bos.flush();
                    bos.close();
                    bis.close();
                }
                zipFile.close();
            } catch (IOException e) {
            }
            //end-----解压jar

            ClassToJava class2java = new ClassToJava();
            class2java.listFolder(this.thisjardir, this.classfilePath, this.codedir, this.apkName);
        }

        try {
            Thread.sleep(5000);
        } catch (InterruptedException ex) {
        }
        ctj.deleteFile(new File(codedir + "\\" + apkName + "\\class\\"));
        ctj.deleteFile(new File(codedir + "\\" + apkName + "\\dex\\"));
        ctj.deleteFile(new File(codedir + "\\" + apkName + "\\apktool.yml"));
        if (this.smali.equals("no")) {
            ctj.deleteFile(new File(codedir + "\\" + apkName + "\\smali\\"));
        }
        jLabel.setText(" 输出完成");
        //end-----反编译class
    }
}
